package org.scaffold.velocity;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.scaffold.jdbc.TableInfo;
import org.scaffold.utils.LogUtils;

import javax.swing.filechooser.FileSystemView;
import java.io.*;
import java.util.Date;

/**
 *
 */
public class TemplateUtils {

    public static File newFile(String path, String name) throws IOException {
        File pathFile = new File(path);
        if (!pathFile.exists()) {
            pathFile.mkdirs();
        }
        File file = new File(pathFile, name);
        file.createNewFile();
        return file;
    }

    public static File getHomeDirectory() {
        return FileSystemView.getFileSystemView()
                .getHomeDirectory();
    }

    /**
     * 初始化 VelocityEngine
     *
     * @return 已初始化
     */
    public static VelocityEngine initVelocityEngine() {
        VelocityEngine ve = new VelocityEngine();
        ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
        ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        ve.init();
        return ve;
    }

    private static final String DOMAIN_TEMPLATE_NAME = "/templates/domain.vm";
    private static final String XML_TEMPLATE_NAME = "/templates/xml.vm";
    private static final String MAPPER_TEMPLATE_NAME = "/templates/mapper.vm";
    private static final String QUERY_MODEL_TEMPLATE_NAME = "/templates/queryModel.vm";
    private static final String SERVICE_TEMPLATE_NAME = "/templates/service.vm";
    private static final String CONTROLLER_TEMPLATE_NAME = "/templates/controller.vm";

    private static final String FILE_JAVA_SUFFIX = "%s.java";
    private static final String FILE_MAPPER_SUFFIX = "%sMapper.java";
    private static final String QUERY_MODEL_XML_SUFFIX = "Query%sModel.java";
    private static final String FILE_XML_SUFFIX = "%sMapper.xml";
    private static final String FILE_SERVICE_SUFFIX = "%sService.java";
    private static final String FILE_CONTROLLER_SUFFIX = "%sController.java";

    private static final String SAVE_FILE_ENCODE = "utf-8";


    public static void doTemplate(TableInfo info, String path, boolean domain, boolean mapper,
                                  boolean controller, boolean service, boolean xml) throws IOException {
        VelocityContext ctx = new VelocityContext(info.transMap(null));
        ctx.put("author", System.getProperty("user.name"));
        ctx.put("time", DateFormatUtils.ISO_DATE_FORMAT.format(new Date()));
        VelocityUtils velocityUtils = new VelocityUtils();
        ctx.put("v_utils", velocityUtils);

        if (domain) {
            LogUtils.info("正在生成domain");
            saveFile(DOMAIN_TEMPLATE_NAME, FILE_JAVA_SUFFIX, info, path, ctx);
        }
        if (xml) {
            LogUtils.info("正在生成xml");
            saveFile(XML_TEMPLATE_NAME, FILE_XML_SUFFIX, info, path, ctx);
        }
        boolean isSaveMode = false;
        if (info.getImportPackage().contains(info.getPrimaryKey().getJavaTypeName())) {
            ctx.put("_package_key", info.getPrimaryKey().getJavaTypeName());
        } else {
            ctx.put("_package_key", "");
        }
        if (mapper) {
            LogUtils.info("正在生成mapper");
            saveFile(MAPPER_TEMPLATE_NAME, FILE_MAPPER_SUFFIX, info, path, ctx);
            isSaveMode = true;
        }
        if (service) {
            LogUtils.info("正在生成service");
            saveFile(SERVICE_TEMPLATE_NAME, FILE_SERVICE_SUFFIX, info, path, ctx);
            isSaveMode = true;
        }
        if (controller) {
            LogUtils.info("正在生成controller");
            saveFile(CONTROLLER_TEMPLATE_NAME, FILE_CONTROLLER_SUFFIX, info, path, ctx);
            isSaveMode = true;
        }

        if (isSaveMode) {
            saveFile(QUERY_MODEL_TEMPLATE_NAME, QUERY_MODEL_XML_SUFFIX, info, path, ctx);
        }
    }

    private static void saveFile(String templateName, String fileSuffix, TableInfo info, String path, VelocityContext ctx) throws IOException {
        Template template = initVelocityEngine().getTemplate(templateName, SAVE_FILE_ENCODE);
        File file = newFile(String.format("%s%s%s", path, "/", info.getJavaName()), String.format(fileSuffix, info.getJavaName()));
        OutputStream outputStream = new FileOutputStream(file);
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, SAVE_FILE_ENCODE);
        template.merge(ctx, writer);
        try {
            writer.flush();
        } finally {
            writer.close();
        }
    }
}
